#ifndef _SERVER_H_
#define _SERVER_H_

#include <cstring>
#include <map>
#include "Blowfish.h"
#include "PracticalSocket.h"
#include "randNum.h"

// keyS|idA|, keyLength + idLength < 30. // 32
#define INNER_BUFFER_LENGTH 64
// enc[keyS|idA|idB|nonceA|enc[keyS|idA|]|], idA|idB|nonceA, keyLength * 2 + idLength * 3 + nonceLength < 12 < 121. // 128
#define MAX_BUFFER_LENGTH 128

/*
 * Comaprator for maps.
 */
struct cmp_str {
	bool operator() (char const *a, char const *b) {
		return strcmp(a, b) < 0;
	}
};

/*
 * Class which represents a server.
 */
class Server {
	private:
		int encryptionOn;
		char* protocol;
		int sequenceNumberRange;
		int packetSize;
		int timeoutInterval;
		char* keyB;
		char* nonceB;
		char* idB;
		int port;
		long fNonceB;
		int windowSize;
		pthread_mutex_t parseMutex;
	public:
		Server(int, char*, int, int, int, char*, char*, int, int);
		~Server();
		int getEncryptionOn();
		char* getProtocol();
		int getSequenceNumberRange();
		int getPacketSize();
		int getTimeoutInterval();
		char* getKeyB();
		char* getNonceB();
		void setIdB(char*);
		char* getIdB();
		int getPort();
		void handleTCPRequest(TCPSocket*);
		int getWindowSize();
		char* fileName;
};
/*
 * Server Constructor.
 */
Server::Server(int encryptionIn, char* protocolIn, int sequenceNumberIn, int packetSizeIn, int timeoutIntervalIn, char* keyBIn, char* nonceBIn, int portIn, int windowSizeIn) {
	encryptionOn = encryptionIn;
	protocol= protocolIn;
	sequenceNumberRange = sequenceNumberIn;
	packetSize = packetSizeIn;
	timeoutInterval = timeoutIntervalIn;
	keyB = keyBIn;
	nonceB = nonceBIn;
	port = portIn;
	windowSize = windowSizeIn;
	fNonceB = randNum((long) atoi(nonceB));
	pthread_mutex_init(&parseMutex, NULL);
}
/*
 * Server Destructor.
 */
Server::~Server() {
	delete[] protocol;
	delete[] keyB;
	delete[] nonceB;
	delete[] idB;
}
/*
 * Server getEncryptionOn.
 */
int Server::getEncryptionOn() {
	return encryptionOn;
}
/*
 * Server getProtocol.
 */
char* Server::getProtocol() {
	return protocol;
}
/*
 * Server getSequenceNumberRange.
 */
int Server::getSequenceNumberRange() {
	return sequenceNumberRange;
}
/*
 * Server getPacketSize.
 */
int Server::getPacketSize() {
	return packetSize;
}
/*
 * Server getTimeoutInterval.
 */
int Server::getTimeoutInterval() {
	return timeoutInterval;
}
/*
 * Server getKeyB.
 */
char* Server::getKeyB() {
	return keyB;
}
/*
 * Server getNonceB.
 */
char* Server::getNonceB() {
	return nonceB;
}
/*
 * Server setIdB.
 */
void Server::setIdB(char* idBIn) {
	idB = idBIn;
}
/*
 * Server getIdB.
 */
char* Server::getIdB() {
	return idB;
}
/*
 * Server getPort.
 */
int Server::getPort() {
	return port;
}
/*
 * Server getWindowSize.
 */
int Server::getWindowSize() {
	return windowSize;
}

#endif
